package com.liliudong.keelflower.upms.biz.service.sys.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liliudong.keelflower.common.core.constants.Const;
import com.liliudong.keelflower.common.core.constants.HttpStatus;
import com.liliudong.keelflower.common.core.exception.BusinessException;
import com.liliudong.keelflower.common.core.utils.CacheUtils;
import com.liliudong.keelflower.upms.biz.dao.sys.SysUserDao;
import com.liliudong.keelflower.upms.biz.entity.sys.SysUser;
import com.liliudong.keelflower.upms.biz.service.sys.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author liudong.li
 * @since 2021-06-07
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserService {

    private final RedisTemplate<String, SysUser> sysUserRedisTemplate;
    private final RedisTemplate<String, Long> longRedisTemplate;

    @Override
    public SysUser getById(Serializable id) {
        String userRedisKey = CacheUtils.SysUser.user(id);
        HashOperations<String, String, SysUser> hashOperations = sysUserRedisTemplate.opsForHash();
        SysUser sysUser = hashOperations.get(userRedisKey, CacheUtils.SysUser.USER);
        if (Objects.isNull(sysUser)) {
            sysUser = baseMapper.selectById(id);
            if (Objects.nonNull(sysUser)) {
                hashOperations.put(userRedisKey, CacheUtils.SysUser.USER, sysUser);
            }
        }
        return sysUser;
    }

    @Override
    public String login(String username, String password) {
        ValueOperations<String, Long> valueOperations = longRedisTemplate.opsForValue();
        SysUser sysUserEntity = baseMapper.selectOne(
                new LambdaQueryWrapper<SysUser>()
                        .eq(SysUser::getUsername, username)
        );
        if (Objects.isNull(sysUserEntity)) {
            throw new BusinessException(HttpStatus.UNKNOWN_ACCOUNT);
        }
        if (Const.SysUser.Status.LOCKED.status == sysUserEntity.getStatus()) {
            throw new BusinessException(HttpStatus.DISABLED_ACCOUNT);
        }
        if (!DigestUtil.bcryptCheck(password, sysUserEntity.getPassword())) {
            throw new BusinessException(HttpStatus.SECRET_EXCEPTION);
        }
        String token = IdUtil.simpleUUID();
        valueOperations.set(CacheUtils.SysUser.token(token), sysUserEntity.getId(), CacheUtils.SysUser.EXPIRE_TIME, TimeUnit.SECONDS);
        return token;
    }

    @Override
    public void logout(String token) {
        longRedisTemplate.delete(CacheUtils.SysUser.token(token));
    }
}
